package semant.firstpass;

import semant.Env;
import symbol.ClassInfo;
import symbol.MethodInfo;
import symbol.Symbol;
import syntaxtree.MethodDecl;
import syntaxtree.VisitorAdapter;
import util.List;

public class MethodDeclHandler extends VisitorAdapter
{
	private Env e;
	private ClassInfo ci;
	
	private MethodDeclHandler(Env e, ClassInfo ci)
	{
		super();
		this.e = e;
		this.ci = ci;
	}
		
	public static void firstPass(Env e, ClassInfo ci, List<MethodDecl> list) 
	{
		MethodDeclHandler h = new MethodDeclHandler(e, ci);
		
		for(List<MethodDecl> m = list; m != null; m = m.tail)
			m.head.accept(h);
	}
	
	public void visit(MethodDecl node)
	{
		Symbol name = Symbol.symbol(node.name.s);
		MethodInfo mi = new MethodInfo(node.returnType, name, ci.name);
				
		FormalHandler.firstPass(e, mi, node.formals);
		VarDeclHandler.firstPass(e, ci, mi, node.locals);
		
		if(!ci.addMethod(mi))
		{
			MethodInfo old = ci.methods.get(name);
			e.err.Error(node.name, new Object[]{"Metodo \'" + name + "\' redeclarado para classe \'" + ci.name + "\' , Declaracao anterior aqui: [" + old.type.line + "," + old.type.row + "]"});
		}
	}
}
